﻿using System;
using System.Collections;

namespace Lesson4_Hashtable
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("哈希表");

            #region 知识点一 Hashtable的本质
            //Hashtable（又称散列表） 是基于键的哈西代码组织起来的 键/值为一对
            //它的主要作用是提高数据查询的效率
            //使用键来访问集合中的元素  
            #endregion

            #region 知识点二 申明
            //需要引用命名空间  using System.Collections;
            Hashtable hashtable = new Hashtable();
            #endregion

            #region 知识点三 增删查改

            #region 增
            //键与值的类型都可以随意写 因为他们是object类型
            hashtable.Add(1, "123");
            hashtable.Add("123", 2);
            hashtable.Add(true, false);
            hashtable.Add(false, false);

            //注意：不能出现相同的键 值可以重复 会报错
            //hashtable.Add(1, "as");
            #endregion
            #region 删
            //1.只能通过键去删除 删除会直接把键和值都删除
            hashtable.Remove(1);
            //2.删除不存在的键 不会报错但也没反应
            hashtable.Remove(2);
            //3.可以直接清空
            hashtable.Clear();

            hashtable.Add(1, "123");//以便后面查看或遍历
            hashtable.Add(2, "1234");
            hashtable.Add("1235", 1);
            #endregion
            #region 查
            //1.通过键查看值
            //  找不到会返回空
            Console.WriteLine(hashtable[1]);
            Console.WriteLine(hashtable[3]);//找不到的值 他会返回空 在控制台那里空一行
            Console.WriteLine(hashtable["1235"]);

            //2.查看是否存在
            //根据键检测  判断有没有这个键的键值对
            if (hashtable.Contains(2))
            {
                Console.WriteLine("存在键为2的键值对");
            }else Console.WriteLine("不存在键为2的键值对");

            if (hashtable.ContainsKey(2))//此方法与上面的方法是一样的
            {
                Console.WriteLine("存在键为2的键值对");
            }

            //根据值检测
            if (hashtable.ContainsValue("1234"))
            {
                Console.WriteLine("存在值为\"1234\"的键值对");
            }
            #endregion
            #region 改
            //只能改 键对应的值内容 无法修改键
            Console.WriteLine("修改前："+hashtable[1]);
            hashtable[1] = 100.5f;//赋值修改
            Console.WriteLine("修改后：" + hashtable[1]);
            #endregion

            #endregion
            #region 知识点四 遍历
            //得到键值对 对数
            Console.WriteLine(hashtable.Count);

            //1.遍历所有键
            Console.WriteLine("**********foreach遍历所有键*************");
            foreach (object item in hashtable.Keys)//遍历的顺序并不像其他数据结构那样有规律
            {
                Console.WriteLine("键:" + item);
                Console.WriteLine("值:" + hashtable[item]);//通过遍历的键寻找值
            }

            //2.遍历所有值
            Console.WriteLine("**********foreach遍历所有值*************");
            foreach (object item in hashtable.Values)//没有方法能通过值寻找键
            {
                Console.WriteLine("值:" + item);
            }
            //3.键值对一起遍历
            Console.WriteLine("**********foreach一起遍历键值对*************");
            foreach (DictionaryEntry item in hashtable)//没有方法能通过值寻找键
            {
                Console.WriteLine("键:"+item.Key+"   值:" + item.Value);
            }
            //4.迭代器遍历法  
            Console.WriteLine("**********迭代器遍历键值对*************");
            //迭代器                                  返回一个字典枚举器
            IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator();
            bool flag = myEnumerator.MoveNext();//第一次调用会到初始位置 游标 每次调用都往后面移一位  后面如果有键值对的话 返回true
            // myEnumerator.MoveNext()将枚举数推进到集合的下一个元素。
            while (flag)
            {
                Console.WriteLine("键:" + myEnumerator.Key + "   值:" + myEnumerator.Value);
                flag = myEnumerator.MoveNext();
            }
            #endregion

            #region 知识点五 装箱拆箱
            //由于用万物之父来存储数据，自然存在装箱拆箱
            //当往其中进行值类型存储时就是在装箱
            //当将值类型对象取出来转换使用时，就存在拆箱
            #endregion

            #region 练习题
            //1.请描述Hashtable的存储规则

            //2.制作一个怪物管理器，提供创建 ，移除怪物的方法。每个 怪物都有自己的唯一ID

            #endregion
        }
    }
}
